package com.vpen.client.heard;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.web.socket.*;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
import org.springframework.web.socket.handler.ConcurrentWebSocketSessionDecorator;

import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * 描述
 *
 * @author 韦鹏
 * @date 2022/11/24 23:06
 */
@Slf4j
public class HeardClient {

    private static String URL = "ws://localhost:8099/hello/ping-2";

//    private static WebSocketSession session;

    public static void main(String[] args) {

        try {
            WebSocketSession  session = HeardClient.connect();

            Scanner scanner = new Scanner(System.in);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                // 如果是空的，就发送ping,不是就发送输入的
                if (StrUtil.isBlank(line)) {
                    sendPing(session);
                } else {
                    session.sendMessage(new TextMessage(line));
                }
            }
        } catch (InterruptedException | ExecutionException | IOException e) {
            log.error("连接异常");
            throw new RuntimeException(e);
        }

    }


    /**
     * 连接操作
     */
    public static WebSocketSession connect() throws InterruptedException, ExecutionException, IOException {
        StandardWebSocketClient client = new StandardWebSocketClient();
        ListenableFuture<WebSocketSession> future = client.doHandshake(new HeardWebSocketHandler(), URL);
        WebSocketSession session = future.get();
        // 并发保证只有一个线程发送
        ConcurrentWebSocketSessionDecorator sessionDecorator = new ConcurrentWebSocketSessionDecorator(session, 3000, 1024);
        sessionDecorator.sendMessage(new TextMessage("hello,server"));
        return session;
    }

    /**
     * 断线重连
     */
    public static void reconnect() {
        CompletableFuture.runAsync(() -> {
            log.debug("异步连接");
            WebSocketSession connect = null;
            while (connect == null) {
                try {
                    connect = connect();
                    log.debug("connect:{}", connect);
                    Thread.sleep(1000);
                } catch (InterruptedException | IOException | ExecutionException ignored) {

                }
            }
            sendPing(connect);
        });
    }

    /**
     * 发送ping
     */
    public static void sendPing(WebSocketSession session) {
        try {
            session.sendMessage(new PingMessage());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }


}
